home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / cgazv3n4.zip / DOS4-DIR.ZIP / DOS4.C < prev    next >
Text File  |  1989-04-11  |  12KB  |  333 lines

  1. /**************************** DOS4.C **********************************\
  2. |*                                                                    *|
  3. |* DOS4.C - demonstrate usage of extended DOS 4.0 disk functions      *|
  4. |*                                                                    *|
  5. |* (c) Copyright 1989, David Craig.  All rights reserved.             *|
  6. |* Permission is granted to incorporate these functions into a larger *|
  7. |* work and to distribute the resulting executable file.              *|
  8. |*                                                                    *|
  9. |* Usage: dos4 drive                                                  *|
  10. |*                                                                    *|
  11. |* Returns: detailed disk summary for given drive                     *|
  12. |*                                                                    *|
  13. |* Compilers: TurboC 2.0, MSC 5.1                                     *|
  14. |* Memory models: any                                                 *|
  15. \**********************************************************************/
  16.  
  17. /* must prevent MSC from word aligning contents of our structures */
  18. #pragma pack (1)
  19.  
  20. #include "local.h"
  21. #include "dos4.h"
  22. #if !defined(MK_FP)
  23. #define MK_FP(seg,ofs) ((void far *) (((unsigned long)(seg)<<16) \
  24.                        | (unsigned)(ofs)))
  25. #endif
  26.  
  27. #define TRUE            1
  28. #define ENTRY_LENGTH    32
  29.  
  30. int     save_current_drive;
  31. struct  disk_table tbl;
  32. struct  packet pkt;
  33. dword   not_used_sectors;
  34. word    abs_read_error;
  35.  
  36. int     abs_read(int drive, word nsectors, word sector, void *buffer);
  37. word    getdfs(int drive, word *avail, word *total, word *sectsize);
  38. int     current_drv(void);
  39. struct  disk_table far *get_table(int drv);
  40. void    print_vol(int drive, struct disk_table *tbl);
  41. void    print_disk_tbl(int drive, struct disk_table *tbl);
  42. void    print_bios_parameter_block(int drive, struct boot *bpb);
  43. void    check_compatibility(int drive, struct boot *bpb,
  44.         struct disk_table *tbl);
  45. void    print_master_boot_record(int drive);
  46. void    print_error_message(void);
  47.  
  48. int main(int argc, char **argv)
  49. {
  50.     int     drive;
  51.     int     ver;
  52.     struct  disk_table far *tbl_ptr;
  53.     struct  boot *bpb;
  54.  
  55.     printf("%s (c) 1989 David J. Craig, All rights reserved.\n",
  56.         argv[0]);
  57.     if(signal(SIGINT, SIG_IGN) == SIG_ERR)
  58.     {
  59.         cputs("\r\nCouldn't set SIGINT.\r\n");
  60.         abort();
  61.     }
  62.     ver = _osmajor * 100 + _osminor;
  63.     if(ver < 400 || ver > 409)
  64.     {
  65.         printf("\aIncorrect DOS version %d.%02d.\n\a", _osmajor, _osminor);
  66.         abort();
  67.     }
  68.     if(argc > 1)
  69.     {
  70.         drive = tolower(*argv[1]) - 'a';
  71.     }
  72.     else
  73.     {
  74.         printf("\nDrive must be specified.\n\a");
  75.         abort();
  76.     }
  77.     bpb = (struct boot *) malloc(2048);
  78.     if(bpb == NULL)
  79.     {
  80.         fprintf(stderr, "\n\aInsufficient memory available.\n\a");
  81.         abort();
  82.     }
  83.     if(abs_read(drive, 1, 0, bpb))
  84.     {
  85.         fprintf(stderr, "\n\aUnable to read drive via INT 25h.\n\a");
  86.         print_error_message();
  87.         abort();
  88.     }
  89.     tbl_ptr = get_table(drive);
  90.     tbl = *tbl_ptr;
  91.     print_disk_tbl(drive, &tbl);
  92.     print_bios_parameter_block(drive, bpb);
  93.     free(bpb);
  94.     return(0);
  95. }
  96.  
  97. void print_error_message()
  98. {
  99.     word    upper;
  100.     word    lower;
  101.  
  102.     upper = (abs_read_error & 0xff00) >> 8;
  103.     lower = abs_read_error & 0x00ff;
  104.     switch(upper)
  105.     {
  106.         case    0x80:
  107.             fprintf(stderr, "Attachment failed to respond.\n");
  108.             break;
  109.         case    0x40:
  110.             fprintf(stderr, "SEEK operation failed.\n");
  111.             break;
  112.         case    0x08:
  113.             fprintf(stderr, "Bad CRC on diskette read.\n");
  114.             break;
  115.         case    0x04:
  116.             fprintf(stderr, "Requested sector not found.\n");
  117.             break;
  118.         case    0x03:
  119.             fprintf(stderr, "Write attempt on write-protected diskette.\n");
  120.             break;
  121.         case    0x02:
  122.             fprintf(stderr, "Error other than types listed above.\n");
  123.             break;
  124.         default:
  125.             fprintf(stderr, "Unknown error - AH = 0x%02X.\n", upper);
  126.             break;
  127.     }
  128.     switch(lower)
  129.     {
  130.         case    0x00:
  131.             fprintf(stderr, "Attempt to write on write-protected diskette.\n");
  132.             break;
  133.         case    0x01:
  134.             fprintf(stderr, "Unknown unit.\n");
  135.             break;
  136.         case    0x02:
  137.             fprintf(stderr, "Drive not ready.\n");
  138.             break;
  139.         case    0x03:
  140.             fprintf(stderr, "Unknown command.\n");
  141.             break;
  142.         case    0x04:
  143.             fprintf(stderr, "Data error (CRC).\n");
  144.             break;
  145.         case    0x05:
  146.             fprintf(stderr, "Bad request structure length.\n");
  147.             break;
  148.         case    0x06:
  149.             fprintf(stderr, "Seek error.\n");
  150.             break;
  151.         case    0x07:
  152.             fprintf(stderr, "Unknown media type.\n");
  153.             break;
  154.         case    0x08:
  155.             fprintf(stderr, "Sector not found.\n");
  156.             break;
  157.         case    0x09:
  158.             fprintf(stderr, "Printer out of paper.\n");
  159.             break;
  160.         case    0x0a:
  161.             fprintf(stderr, "Write fault.\n");
  162.             break;
  163.         case    0x0b:
  164.             fprintf(stderr, "Read fault.\n");
  165.             break;
  166.         case    0x0c:
  167.             fprintf(stderr, "General failure.\n");
  168.             break;
  169.         default:
  170.             fprintf(stderr, "Unknown error - AL = 0x%02X.\n", lower);
  171.             break;
  172.     }
  173.     return;
  174. }
  175.  
  176. void print_disk_tbl(int drive, struct disk_table *tbl)
  177. {
  178.     printf("\nDOS function 32h Disk's Table for Drive   = %c:.\n\n",
  179.         drive + 'A');
  180.     printf("Assigned Disk                             = %u.\n",
  181.         tbl->designator);
  182.     printf("Unit Number                               = %u.\n",
  183.         tbl->unit_number);
  184.     printf("Bytes per Sector                          = %u.\n",
  185.         tbl->sector_size);
  186.     printf("Sectors per cluster - 1                   = %u.\n",
  187.         tbl->cluster_size);
  188.     printf("Shift Count for Sector/Cluster Conversion = %u.\n",
  189.         tbl->shift_value);
  190.     printf("Fat Start (Reserved Sectors)              = %u.\n",
  191.         tbl->fat_start);
  192.     printf("Number of copies of the FAT               = %u.\n",
  193.         tbl->fat_copies);
  194.     printf("Maximum Directory Entries                 = %u.\n",
  195.         tbl->max_entries);
  196.     printf("First Usable Sector (Data Begins)         = %u.\n",
  197.         tbl->first_sector);
  198.     printf("Total Cluster Count                       = %u.\n",
  199.         tbl->last_cluster);
  200.     printf("Sectors in FAT                            = %u.\n",
  201.         tbl->fat_size);
  202.     printf("First Directory Sector                    = %u.\n",
  203.         tbl->dir_start);
  204.     printf("Media Descriptor                          = %X.\n",
  205.         tbl->media_type);
  206.     printf("Device Driver Address                     = %Fp.\n",
  207.         tbl->ddh);
  208.     printf("Drive Used Flag                           = %X.\n",
  209.         tbl->drive_used);
  210.     printf("Chain to Next Disk Table                  = %Fp.\n",
  211.         tbl->nxt);
  212.     if(FP_OFF(tbl->nxt) != 0xffff)
  213.         printf("Assigned Disk (Next Disk Table)           = %c:.\n",
  214.         tbl->nxt->designator + 'A');
  215.     else
  216.         printf("Last Disk Table in Chain.\n");
  217.     printf("\n");
  218.     return;
  219. }
  220.  
  221. void print_bios_parameter_block(int drive, struct boot *bpb)
  222. {
  223.     int     i;
  224.  
  225.     printf("\nBIOS Parameter Block for Drive           = %c:.\n\n",
  226.         drive + 'A');
  227.     printf("First 3 bytes (jump)                     = %X%X%X.\n",
  228.         bpb->jump[0], bpb->jump[1], bpb->jump[2]);
  229.     printf("OEM Name                                 = ");
  230.     for(i = 0; i < 8; i++)
  231.         putchar(bpb->oem_name[i]);
  232.     printf(".\n");
  233.     printf("Bytes per sector                         = 0x%04X - %u.\n",
  234.         bpb->bytes_per_sector, bpb->bytes_per_sector);
  235.     printf("Sectors per allocation unit              = 0x%02X.\n",
  236.         bpb->sectors_per_au);
  237.     printf("Reserved sectors (FAT start)             = 0x%04X.\n",
  238.         bpb->reserved_sectors);
  239.     printf("Number of FATs                           = 0x%02X.\n",
  240.         bpb->number_of_fats);
  241.     printf("Maximum number of root directory entries = 0x%04X - %u.\n",
  242.         bpb->number_of_entries, bpb->number_of_entries);
  243.     if(bpb->number_of_sectors)
  244.     {
  245.         printf("Number of sectors                        = 0x%04X - %u.\n",
  246.             bpb->number_of_sectors, bpb->number_of_sectors);
  247.     }
  248.     else
  249.     {
  250.         printf("Number of sectors                        = Zero.\n");
  251.     }
  252.     printf("Media descriptor                         = %02X.\n",
  253.         bpb->media_descriptor);
  254.     printf("FAT size                                 = %u.\n",
  255.         bpb->fat_size);
  256.     printf("Sectors per track                        = %u.\n",
  257.         bpb->sectors_per_track);
  258.     printf("Number of heads                          = %u.\n",
  259.         bpb->number_of_heads);
  260.     printf("Number of hidden sectors                 = 0x%lX - %lu.\n",
  261.         bpb->hidden_sectors, bpb->hidden_sectors);
  262.     printf("Big number of sectors                    = 0x%lX - %lu.\n",
  263.         bpb->big_number_of_sectors, bpb->big_number_of_sectors);
  264.     printf("Physical drive number                    = 0x%02X.\n",
  265.         bpb->physical_drive_number);
  266.     printf("Reserved                                 = 0x%02X.\n",
  267.         bpb->bpb_reserved);
  268.     printf("Extended boot record signature           = 0x%02X.\n",
  269.         bpb->extended_boot_record_sig);
  270.     if(bpb->extended_boot_record_sig == 0x29)
  271.     {
  272.         printf("Volume serial number                     = %04X-%04X.\n",
  273.             FP_SEG(bpb->volume_serial_number),
  274.             FP_OFF(bpb->volume_serial_number));
  275.         printf("Volume Label                             = ");
  276.         for(i = 0; i < 11; i++)
  277.             putchar(bpb->volume_label[i]);
  278.         printf(".\n");
  279.         printf("BIOS Parameter Block FAT Size            = ");
  280.         for(i = 0; i < 8; i++)
  281.             putchar(bpb->bpb_fat_id[i]);
  282.         printf(".\n");
  283.     }
  284.     printf("\n");
  285.     return;
  286. }
  287.  
  288. int abs_read(int drive, word nsectors, word sector, void *buffer)
  289. {
  290.     union   REGS regs;
  291.     struct  SREGS sregs;
  292.     struct  packet far *packt;
  293.  
  294.     /* first try a standard read */
  295.     regs.h.al = ( byte ) drive;
  296.     regs.x.cx = nsectors;
  297.     regs.x.dx = sector;
  298.     segread(&sregs);
  299.     regs.x.bx = (word) buffer;
  300.     (void) int86x(0x25, ®s, ®s, &sregs);
  301.  
  302.     /* DOS 4.x will tell us if we are reading a 32meg+ partition... */
  303.     if(regs.x.cflag && regs.x.ax == 0x0207)
  304.     {
  305.         packt = (struct packet far *) &pkt;     /* must set up packet */
  306.         regs.h.al = ( byte ) drive;
  307.         pkt.starting_sector = (dword) sector;
  308.         pkt.nbr_sectors = nsectors;
  309.         pkt.buffer = buffer;
  310.         sregs.ds = FP_SEG(packt);
  311.         regs.x.bx = FP_OFF(packt);
  312.         regs.x.cx = 0xffff;
  313.         (void) int86x(0x25, ®s, ®s, &sregs);  /* read again */
  314.     }
  315.     abs_read_error = regs.x.ax;
  316.     return( (int) regs.x.cflag);
  317. }
  318.  
  319. struct disk_table far *get_table(int drv)
  320. {
  321.     struct  disk_table far *t;
  322.     union   REGS regs;
  323.     struct  SREGS segregs;
  324.  
  325.     regs.x.ax = 0x3200;
  326.     regs.x.dx = drv + 1;
  327.     segread(&segregs);
  328.     intdosx(®s, ®s, &segregs);
  329.     t = MK_FP(segregs.ds, regs.x.bx);
  330.     return(t);
  331. }
  332.  
  333.